package user

import (
	"context"
	"errors"
	"fmt"
	"github.com/gogf/gf/v2/crypto/gmd5"
	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/net/ghttp"
	"github.com/google/uuid"
	"github.com/skip2/go-qrcode"
	"image/color"
	v1 "qiyu-contact/api/user/v1"
	"qiyu-contact/internal/dao"
	"qiyu-contact/internal/model/entity"
	"qiyu-contact/internal/service"
	"qiyu-contact/internal/utils"
	"strconv"
	"sync"
)

var (
	lock sync.Mutex
)

type sUser struct{}

func (s *sUser) FindUserAccount(ctx context.Context, req *v1.FindUserAccountReq) (res *v1.FindUserAccountRes, err error) {
	get, err := g.Redis().Get(ctx, req.Uuid)
	if err != nil {
		return nil, err
	}
	_, err = g.Redis().Del(ctx, req.Uuid)
	if err != nil {
		return nil, err
	}
	data, err := dao.WebChatUser.Ctx(ctx).Fields("account").Where("uuid=?", get).One()
	if err != nil {
		return nil, err
	}
	res = &v1.FindUserAccountRes{Account: data["account"].String()}
	return
}

func (s *sUser) Login(ctx context.Context, req *v1.LoginReq) (res *v1.UserDetailRes, err error) {
	var user *entity.WebChatUser
	md5, _ := gmd5.Encrypt(req.Password)
	fmt.Println(md5)
	err = dao.WebChatUser.Ctx(ctx).FieldsEx("password").Where("status_cd", 1).Scan(&user, g.Map{
		"account":  req.Account,
		"password": md5,
	})
	if err != nil {
		return nil, err
	}
	res = &v1.UserDetailRes{
		User: user,
	}
	return
}

func (s *sUser) Register(ctx context.Context, req *v1.RegisterReq) (res *v1.RegisterRes, err error) {
	fromCtx := ghttp.RequestFromCtx(ctx)
	realIP := fromCtx.GetHeader("X-Real-IP")
	if realIP == "" {
		realIP = fromCtx.GetHeader("X-Forwarded-For")
	}
	if realIP == "" {
		realIP = fromCtx.GetRemoteIp()
	}
	if realIP == "" {
		return nil, errors.New("系统异常")
	}
	md5Pwd, _ := gmd5.Encrypt(req.Password)
	newUUID, err := uuid.NewUUID()
	if err != nil {
		lock.Unlock()
		return nil, err
	}
	lock.Lock()
	uid := newUUID.String()
	if err != nil {
		return nil, err
	}
	encryptString, err := gmd5.EncryptString(uid)
	if err != nil {
		return nil, err
	}
	_, err = g.Redis().Set(ctx, encryptString, uid)
	if err != nil {
		return nil, err
	}
	db := dao.WebChatUser.DB()
	if tx, err := db.Begin(ctx); err == nil {
		tx.Save("chat_user", g.Map{})
	}
	count, _ := dao.WebChatUser.Ctx(ctx).Count("id")
	tempAcc := strconv.Itoa(100000 + count + 1)
	generate, err := utils.LocalQr.Generate(ctx, uid, tempAcc, 256, qrcode.Highest, color.Black, color.White, true)
	if err != nil {
		return nil, err
	}
	_, err = dao.WebChatUser.Ctx(ctx).Insert(g.Map{
		"nickName": req.NickName,
		"account":  tempAcc,
		"uuid":     uid,
		"password": md5Pwd,
		"login_at": realIP,
		"qrcode":   generate,
	})
	lock.Unlock()
	if err != nil {
		lock.Unlock()
		return nil, err
	}

	res = &v1.RegisterRes{Uuid: encryptString}
	return
}
func (s *sUser) FindUserFriend(ctx context.Context, req *v1.GetUserFriendReq) (res *v1.GetUserFriendRes, err error) {
	identity := service.Auth().GetIdentity(ctx)
	var friendList []*entity.WebChatFriendUnion
	baseDB := dao.WebChatFriend.DB()
	err = baseDB.Model("web_chat_user").
		As("ut").
		RightJoin("web_chat_friend wcf2", "ut.id=wcf2.friend_id").
		Fields("ut.id,ut.uuid,ut.nickname,ut.account,ut.avatar,ut.qrcode,ut.signature,ut.online_status,ut.can_account_search,ut.can_add_friend,ut.user_type,ut.login_at,ut.status_cd,ut.created_at,ut.updated_at").
		Fields("wcf2.user_remarks AS user_remarks,wcf2.status_cd AS friend_status_cd").
		Where("ut.id IN (SELECT wcf.friend_id FROM web_chat_friend wcf LEFT JOIN web_chat_user wcu ON wcf.user_id = wcu.id AND wcf.status_cd != 0 WHERE wcf.user_id = ?)", identity).Order("ut.created_at desc").Scan(&friendList)
	if err != nil {
		return nil, err
	}
	res = &v1.GetUserFriendRes{List: friendList}
	return
}
func (s *sUser) GetUserDetail(ctx context.Context, req *v1.GetUserDetailReq) (res *v1.GetUserDetailRes, err error) {
	identity := service.Auth().GetIdentity(ctx)
	user, err := dao.WebChatUser.Ctx(ctx).FieldsEx("password").One("id=?", identity)
	if err != nil {
		return nil, err
	}
	var u entity.WebChatUser
	err = user.Struct(&u)
	if err != nil {
		return nil, err
	}
	res = &v1.GetUserDetailRes{
		WebChatUser: &u,
	}
	return
}
func init() {
	service.RegisterUser(&sUser{})
}
